package com.kingyea.mobilepolice.apimanage.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.google.common.collect.Lists;
import com.kingyea.mobilepolice.apimanage.paraminfo.bean.ParamInfo;
import com.kingyea.mobilepolice.system.Result;
import com.kingyea.mobilepolice.system.exception.BusinessException;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description
 * @date Created in 2018/2/10 10:51
 */
@Component
public class HttpUtil {

    public static Pattern pattern = Pattern.compile("(?<=\\{)[^\\}]+");
    /**
     * logger
     */
//    private static Logger logger = Logger.getLogger(HttpUtil.class);

    private static String CHARSET_UTF8 = GlobalVar.CHARSET_UTF8;
    private static Integer CONNECT_TIMEOUT = 30000;
    private static Integer REAS_TIMEOUT = 30000;
    private static String httpUtilToken;

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url     资源路径（如果url中已经包含参数，则params应该为null）
     * @param params  参数
     * @param headers 请求头属性 {"Connection":"Keep-Alive","Content-Type":"application/json或者application/x-www-form-urlencoded"}
     * @param method  请求方法
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String invokeUrl(String url, Map params, Map<String, String> headers, HttpMethod method) {
        return invokeUrl(url, params, headers, method, CHARSET_UTF8);
    }

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url     资源路径（如果url中已经包含参数，则params应该为null）
     * @param params  参数
     * @param headers 请求头属性 {"Connection":"Keep-Alive","Content-Type":"application/json或者application/x-www-form-urlencoded"}
     * @param method  请求方法
     * @param charset 字符集（一般该为“utf-8”）
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String invokeUrl(String url, Map params, Map<String, String> headers, HttpMethod method, String charset) {
        return invokeUrl(url, params, headers, method, charset, CONNECT_TIMEOUT, REAS_TIMEOUT);
    }

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url            资源路径（如果url中已经包含参数，则params应该为null）
     * @param params         参数
     * @param headers        请求头属性 {"Connection":"Keep-Alive","Content-Type":"application/json或者application/x-www-form-urlencoded"}
     * @param method         请求方法
     * @param charset        字符集（一般该为“utf-8”）
     * @param connectTimeout 连接超时时间（单位为ms）
     * @param readTimeout    读取超时时间（单位为ms）
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String invokeUrl(String url, Map params, Map<String, String> headers, HttpMethod method
            , String charset, int connectTimeout, int readTimeout) {
        // 构造 请求参数的字符串
        String paramsStr = "";
        if (params != null) {

            if (headers != null && headers.entrySet().stream().anyMatch(map -> map.getKey().equalsIgnoreCase("Content-Type") && map.getValue().toUpperCase().contains("JSON"))) {
                // Content-Type 为 JSON格式
                paramsStr = JSON.toJSONString(params);
            } else {
                StringBuilder paramsStrBuilder = new StringBuilder();
                Set<Map.Entry> entries = params.entrySet();
                for (Map.Entry entry : entries) {
                    String value = (entry.getValue() != null) ? (String.valueOf(entry.getValue())) : "";
                    try {
                        paramsStrBuilder.append(entry.getKey() + "=" + URLEncoder.encode(value, CHARSET_UTF8) + "&");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
                paramsStr = paramsStrBuilder.toString();
                if (paramsStr.endsWith("&")) {
                    paramsStr = paramsStr.substring(0, paramsStr.lastIndexOf("&"));
                }
                // get 方法的就把参数拼接到url后面
                if (method.equals(HttpMethod.GET) && !org.springframework.util.StringUtils.isEmpty(paramsStr)) {
                    if (!url.contains("?")) {
                        url += "?" + paramsStr;
                    } else {
                        url += "&" + paramsStr;
                    }
                }
            }
        }

        URL uUrl;
        HttpURLConnection conn = null;
        BufferedWriter out = null;
        BufferedReader in = null;
        try {
            // 创建和初始化连接
            uUrl = new URL(url);
            conn = (HttpURLConnection) uUrl.openConnection();
            // 指定请求header参数
            if (headers != null && headers.size() > 0) {
                Set<String> headerSet = headers.keySet();
                for (String key : headerSet) {
                    conn.setRequestProperty(key, headers.get(key));
                }
            }
            conn.setRequestMethod(method.toString());
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置连接超时时间
            conn.setConnectTimeout(connectTimeout);
            // 设置读取超时时间
            conn.setReadTimeout(readTimeout);

            if (!org.springframework.util.StringUtils.isEmpty(paramsStr) && method != HttpMethod.GET) {
                // 发送请求参数
                out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), charset));
                out.write(paramsStr);
                out.flush();
            }

            //接收返回结果
            StringBuilder result = new StringBuilder();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
            if (in != null) {
                String line = "";
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用接口[" + url + "]失败！请求URL：" + url + "，参数：" + params);
            //处理错误流
            try {
                byte[] buf = new byte[100];
                InputStream errorStream = conn.getErrorStream();
                if (errorStream != null) {
                    StringBuilder errorResult = new StringBuilder();
                    while (errorStream.read(buf) > 0) {
                        errorResult.append(new String(buf));
                    }
                    System.out.println("服务器返回错误信息：" + errorResult.toString());
                    errorStream.close();
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //关闭连接
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

    public static String invokeUrl2(String url, List<ParamInfo> params, Map<String, Object> map, HttpMethod method) {
        return invokeUrl2(url, params, map, method, CHARSET_UTF8, CONNECT_TIMEOUT, REAS_TIMEOUT);
    }

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url            资源路径（如果url中已经包含参数，则params应该为null）
     * @param params         参数详情描述列表
     * @param method         请求方法
     * @param charset        字符集（一般该为“utf-8”）
     * @param connectTimeout 连接超时时间（单位为ms）
     * @param readTimeout    读取超时时间（单位为ms）
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String invokeUrl2(String url, List<ParamInfo> params, Map<String, Object> map, HttpMethod method, String charset, int connectTimeout, int readTimeout) {

        /** 根据 paraminfo 描述设置参数: 1.query 2.body 3.header 4.path 5.formData */
        // 1. query 该参数用?号，拼接到url后
        List<ParamInfo> queryParamList = params.stream().filter(param -> param.getPosition().intValue() == 1).collect(Collectors.toList());
        if (queryParamList != null && queryParamList.size() > 0) {
            url = url.concat("?");
        }
        for (ParamInfo paramInfo : queryParamList) {
            String paramName = paramInfo.getName();
            if (map.containsKey(paramName)) {
                url = url + paramName + "=" + map.get(paramName) + "&";
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }
        url = url.endsWith("&") ? url.substring(0, url.length() - 1) : url;
        url = url.endsWith("?") ? url.substring(0, url.length() - 1) : url;


        // 2. body // TODO: 2018/2/26  暂时为json
        List<ParamInfo> bodyParamList = params.stream().filter(param -> param.getPosition().intValue() == 2).collect(Collectors.toList());
        Map bodyMap = new HashMap();
        for (ParamInfo paramInfo : bodyParamList) {
            String paramName = paramInfo.getName();
            if (map.containsKey(paramName)) {
                bodyMap.put(paramName, map.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }
        String bodyStr = JSON.toJSONString(bodyMap);


        // 3. header
        List<ParamInfo> headerParamList = params.stream().filter(param -> param.getPosition().intValue() == 3).collect(Collectors.toList());
        Map headerMap = new HashMap();
        for (ParamInfo paramInfo : headerParamList) {
            String paramName = paramInfo.getName();
            if (map.containsKey(paramName)) {
                headerMap.put(paramName, map.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }

        // 4. path，替换掉url中{*}对应占位符
        List<ParamInfo> pathParamList = params.stream().filter(param -> param.getPosition().intValue() == 4).collect(Collectors.toList());
        Matcher matcher = pattern.matcher(url);
        while (matcher.find()) {
            for (ParamInfo paramInfo : pathParamList) {
                String paramName = matcher.group();
                if (map.containsKey(paramName)) {
                    url = url.replace("{" + paramName + "}", map.get(paramName).toString());
                } else if (paramInfo.getIsRequired().intValue() == 1) {
                    throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
                }
            }
        }


        // 5. formData
        List<ParamInfo> formDataParamList = params.stream().filter(param -> param.getPosition().intValue() == 5).collect(Collectors.toList());
        Map formDataMap = new HashMap();
        for (ParamInfo paramInfo : formDataParamList) {
            String paramName = paramInfo.getName();
            if (map.containsKey(paramName)) {
                formDataMap.put(paramName, map.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }
        // 序列化成字json符串
        StringBuilder paramsStrBuilder = new StringBuilder();
        Set<Map.Entry> entries = formDataMap.entrySet();
        for (Map.Entry entry : entries) {
            String value = (entry.getValue() != null) ? (String.valueOf(entry.getValue())) : "";
            try {
                paramsStrBuilder.append(entry.getKey() + "=" + URLEncoder.encode(value, CHARSET_UTF8) + "&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        String formDataStr = paramsStrBuilder.toString();
        formDataStr = formDataStr.endsWith("&") ? formDataStr.substring(0, formDataStr.length() - 1) : formDataStr;


//        System.out.println("url:"+url);
//        System.out.println("Header:"+JSON.toJSONString(headerMap));
//        System.out.println("formDataStr:"+formDataStr);
//        System.out.println("bodyStr:"+bodyStr);


        URL uUrl;
        HttpURLConnection conn = null;
        BufferedWriter out = null;
        BufferedReader in = null;
        try {
            // 创建和初始化连接
            uUrl = new URL(url);
            conn = (HttpURLConnection) uUrl.openConnection();
            // 指定请求header参数
            if (headerMap != null && headerMap.size() > 0) {
                Set<String> headerSet = headerMap.keySet();
                for (String key : headerSet) {
                    conn.setRequestProperty(key, headerMap.get(key).toString());
                }
            }
            conn.setRequestMethod(method.toString());
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置连接超时时间
            conn.setConnectTimeout(connectTimeout);
            // 设置读取超时时间
            conn.setReadTimeout(readTimeout);

            if (bodyStr != null && bodyStr.length() > 3 && bodyMap != null && bodyMap.size() > 0 && method != HttpMethod.GET) {
                conn.setRequestProperty("Content-Type", "application/json");
                // 发送请求参数
                out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), charset));
                out.write(bodyStr);
                out.flush();
            } else if (formDataStr != null && formDataStr.length() > 2 && formDataMap != null && formDataMap.size() > 0 && method != HttpMethod.GET) {
                conn.setRequestProperty("Content-Type", "form-data");
                // 发送请求参数
                out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), charset));
                out.write(formDataStr);
                out.flush();
            }

            //接收返回结果
            StringBuilder result = new StringBuilder();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
            if (in != null) {
                String line = "";
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用接口[" + url + "]失败！请求URL：" + url + "，参数：" + params);
            //处理错误流
            String errorStr = "";
            try {
                byte[] buf = new byte[100];
                InputStream errorStream = conn.getErrorStream();
                if (errorStream != null) {
                    StringBuilder errorResult = new StringBuilder();
                    while (errorStream.read(buf) > 0) {
                        errorResult.append(new String(buf));
                    }
                    errorStr = errorResult.toString();
                    System.out.println("服务器返回错误信息：" + errorStr);
                    errorStream.close();
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            throw new BusinessException(StateCode.SYSTEM_ERROR, errorStr);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //关闭连接
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static String httpProcess(HttpServletRequest request) throws IOException, JSONException {
        StringBuffer sb = new StringBuffer();
        InputStream is = request.getInputStream();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(is, GlobalVar.CHARSET_UTF8));
            String s = "";
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            if (sb.toString().length() <= 0) {
                return null;
            } else {
                return sb.toString();
            }
        } finally {
            if (sb != null) {
                is.close();
            }
        }

    }

    public static void main(String[] args) {

        test();

        String url = "http://localhost:8782/test";

        String author = "Basic " + Base64.encode(("admin" + ":" + "123").getBytes());

        Map<String, String> headers = new HashMap<String, String>() {{
            put("Content-Type", "application/json");
            put("Authorization", author);
            put("token", "tom_token");
        }};

        Map<String, Object> params = new HashMap<String, Object>() {{
            put("param1", "中文");
            put("param2", "english");
        }};

        Map params_json = JSON.parseObject("{\"id\":6,\"name\":\"tom6\",\"num\":999}", Map.class);


        String str2 = HttpUtil.invokeUrl(url, params_json, headers, HttpMethod.PUT);
        System.out.println(str2);

        str2 = HttpUtil.invokeUrl(url, params, new HashMap<String, String>() {{
            put("Authorization", author);
            put("token", "tom_token");
        }}, HttpMethod.GET);
        System.out.println(str2);

        str2 = HttpUtil.invokeUrl(url, params_json, headers, HttpMethod.POST);
        System.out.println(str2);


        String content = "src: local{'Open Sans Light'}, local{'OpenSans-Light'}, url(http://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTa-j2U0lmluP9RWlSytm3ho.woff2) format('woff2')";
        // 从内容上截取路径数组
//        Pattern pattern = Pattern.compile("(?<=\\()[^\\)]+");
        Pattern pattern = Pattern.compile("(?<=\\{)[^\\}]+");
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url           资源路径（如果url中已经包含参数，则params应该为null）
     * @param paramInfoList 参数详情描述列表
     * @param paramMap      具体参数（key,value）
     * @param method        请求方法
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static ResponseEntity invokeUrlByRestTemplate(String url, List<ParamInfo> paramInfoList, Map<String, Object> paramMap, HttpMethod method) throws Exception {
        return invokeUrlByRestTemplate(url, paramInfoList, paramMap, method, CHARSET_UTF8, CONNECT_TIMEOUT, REAS_TIMEOUT);
    }

    /**
     * POST方法提交Http请求
     * 注意：Http方法中只有POST方法才能使用body来提交内容
     *
     * @param url            资源路径（如果url中已经包含参数，则params应该为null）
     * @param paramInfoList  参数详情描述列表
     * @param paramMap       具体参数（key,value）
     * @param method         请求方法
     * @param charset        字符集（一般该为“utf-8”）
     * @param connectTimeout 连接超时时间（单位为ms）
     * @param readTimeout    读取超时时间（单位为ms）
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static ResponseEntity<?> invokeUrlByRestTemplate(String url, List<ParamInfo> paramInfoList, Map<String, Object> paramMap, HttpMethod method, String charset, int connectTimeout, int readTimeout) throws Exception {
        /** 根据 paraminfo 描述设置参数: 1.query 2.body 3.header 4.path 5.formData */
        // 1. query 该参数用?号，拼接到url后
        List<ParamInfo> queryParamList = paramInfoList.stream().filter(param -> param.getPosition().intValue() == 1).collect(Collectors.toList());
        if (queryParamList != null && queryParamList.size() > 0) {
            url = url.concat("?");
        }
        for (ParamInfo paramInfo : queryParamList) {
            String paramName = paramInfo.getName();
            if (paramMap.containsKey(paramName)) {
                url = url + paramName + "=" + paramMap.get(paramName) + "&";
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }
        url = url.endsWith("&") ? url.substring(0, url.length() - 1) : url;
        url = url.endsWith("?") ? url.substring(0, url.length() - 1) : url;


        // 2. body // TODO: 2018/2/26  暂时为json
        List<ParamInfo> bodyParamList = paramInfoList.stream().filter(param -> param.getPosition().intValue() == 2).collect(Collectors.toList());
        Map jsonBodyMap = new HashMap();//
        for (ParamInfo paramInfo : bodyParamList) {
            String paramName = paramInfo.getName();
            if (paramMap.containsKey(paramName)) {
                jsonBodyMap.put(paramName, paramMap.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }
//        String bodyStr = JSON.toJSONString(jsonBodyMap);


        // 3. header
        List<ParamInfo> headerParamList = paramInfoList.stream().filter(param -> param.getPosition().intValue() == 3).collect(Collectors.toList());
        Map headerMap = new HashMap();
        for (ParamInfo paramInfo : headerParamList) {
            String paramName = paramInfo.getName();
            if (paramMap.containsKey(paramName)) {
                headerMap.put(paramName, paramMap.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }

        // 4. path，替换掉url中{*}对应占位符
        List<ParamInfo> pathParamList = paramInfoList.stream().filter(param -> param.getPosition().intValue() == 4).collect(Collectors.toList());
        Matcher matcher = pattern.matcher(url);
        while (matcher.find()) {
            for (ParamInfo paramInfo : pathParamList) {
                String paramName = matcher.group();
                if (paramMap.containsKey(paramName)) {
                    url = url.replace("{" + paramName + "}", paramMap.get(paramName).toString());
                } else if (paramInfo.getIsRequired().intValue() == 1) {
                    throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
                }
            }
        }


        // 5. formData
        List<ParamInfo> formDataParamList = paramInfoList.stream().filter(param -> param.getPosition().intValue() == 5).collect(Collectors.toList());
        Map formDataMap = new HashMap();
        for (ParamInfo paramInfo : formDataParamList) {
            String paramName = paramInfo.getName();
            if (paramMap.containsKey(paramName)) {
                formDataMap.put(paramName, paramMap.get(paramName));
            } else if (paramInfo.getIsRequired().intValue() == 1) {
                throw new BusinessException(StateCode.NO_ARGUMENT_ERROR);
            }
        }


        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(readTimeout);// 超时设置
        factory.setConnectTimeout(connectTimeout);
        RestTemplate client = new RestTemplate(factory);
//        client.setMessageConverters(Lists.newArrayList(new StringHttpMessageConverter(Charset.forName(charset))));//字符集  这里不能这样设置，这样会覆盖掉整个list的转换器，这里有很多个转换器
        List<HttpMessageConverter<?>> httpMessageConverterList = client.getMessageConverters();
        for (int i = 0; i < httpMessageConverterList.size(); i++) {
            HttpMessageConverter httpMessageConverter = httpMessageConverterList.get(i);
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                client.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName(charset)));//替换字符串编码转换器
            }
        }


        HttpHeaders headers = new HttpHeaders();
        headers.putAll(headerMap);

        HttpEntity requestEntity = new HttpEntity<Map<String, Object>>(new HashMap() {{
            putAll(paramMap);
        }}, headers);
        if (jsonBodyMap != null && jsonBodyMap.size() > 0 && method != HttpMethod.GET) {// 有 json 参数，并且不是GET
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            requestEntity = new HttpEntity<Map<String, Object>>(new HashMap() {{
                putAll(formDataMap);
                putAll(jsonBodyMap);
            }}, headers);
        } else if (formDataMap != null && formDataMap.size() > 0 && method != HttpMethod.GET) {// 有 formData 参数，并且不是GET
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            requestEntity = new HttpEntity<MultiValueMap<String, Object>>(new LinkedMultiValueMap() {{
                putAll(formDataMap);
                putAll(jsonBodyMap);
            }}, headers);// 表单 MULTIPART_FORM_DATA 的时候 ，参数用MultiValueMap 来封装
        }


//        client.setRequestFactory();
        //  执行HTTP请求
        ResponseEntity response = client.exchange(url, method, requestEntity, Object.class);
        return response;
    }

    private static void test() {
        String url = "http://localhost:8782/serviceInfo/searchByCondition";
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
//  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
//  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        Map<String, Object> params = new HashMap<>();
//  也支持中文
        params.put("username", "用户名");
        params.put("password", "123456");
        params.put("pageSize", 2);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(params, headers);
//        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(params, headers);// 表单 MULTIPART_FORM_DATA 的时候 ，参数用MultiValueMap 来封装
//  执行HTTP请求
        ResponseEntity response = client.exchange(url, HttpMethod.POST, requestEntity, Result.class);
//  输出结果
        System.out.println(response.getBody());
        System.out.println();
    }

    protected static OAuth2ProtectedResourceDetails resource() {
        ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
        resource.setAccessTokenUri("http://localhost:8784/uaa/oauth/token");
        resource.setClientId("gg");
        resource.setClientSecret("mm");
        resource.setScope(Lists.newArrayList("gg"));
        resource.setUsername("admin");
        resource.setPassword("admin");
        return resource;
    }

    /**
     * 测试版本，针对不存本集群的带token请求
     */
    public String invokeUrl2(String url, Map params, Map<String, String> headers, HttpMethod method) throws Exception {
        AccessTokenRequest atr = new DefaultAccessTokenRequest();
        OAuth2RestTemplate client = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
        /** 维护token全局变量，防止每次都发起token获取，但是，如果分别请求多个系统，那必须每次都发起tokan请求，或者维护多个tokan */
        if (StringUtils.isEmpty(httpUtilToken)) {
            OAuth2AccessToken token = client.getAccessToken();
            System.out.println(token.getValue());
            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            if (token != null && !StringUtils.isEmpty(token.getValue())) {
                httpUtilToken = token.getValue();
            } else {
                throw new Exception("123");
            }
        }

        url = url + "?access_token=" + httpUtilToken;

//        client.setInterceptors(Collections.singletonList(oauth2FeignRequestInterceptor));
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Authorization", "Bearer " + httpUtilToken);
        for (String s : headers.keySet()) {
            httpHeaders.set(s, headers.get(s));
        }

//  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
//  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
//        Map<String, Object> params = new HashMap<>();
//  也支持中文


        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(params, httpHeaders);
//        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(params, headers);// 表单 MULTIPART_FORM_DATA 的时候 ，参数用MultiValueMap 来封装
//  执行HTTP请求
        ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);
//  输出结果
        System.out.println(response.getBody());
        System.out.println();
        return response.getBody();
//        return "";
    }


}
